package logistics;

import salesSystem.model.Order;
import salesSystem.model.OrderItem;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

public class LogisticsManagementSystem {
    private Map<String, Shipment> shipments = new HashMap<>();
    private Map<String, Carrier> carriers = new HashMap<>();
    
    public static void main(String[] args) {
        LogisticsManagementSystem logisticsSystem = new LogisticsManagementSystem();
        
        // 初始化承运商
        logisticsSystem.initializeCarriers();
        
        // 模拟从销售系统接收订单
        OrderItem item1 = new OrderItem("P1001", "笔记本电脑", 1, 5999.00);
        OrderItem item2 = new OrderItem("P1002", "无线鼠标", 2, 99.50);
        Order order = new Order("CUST001", List.of(item1, item2), "北京市海淀区中关村大街1号");
        order.setOrderId("ORD20230001");
        order.setStatus(Order.Status.PROCESSING);
        
        System.out.println("=== 物流管理系统启动 ===");
        
        // 1. 创建发货单
        Shipment shipment = logisticsSystem.createShipment(order);
        System.out.println("创建发货单: " + shipment.getShipmentId());
        
        // 2. 分配承运商
        Carrier assignedCarrier = logisticsSystem.assignCarrier(shipment.getShipmentId());
        System.out.println("分配承运商: " + assignedCarrier.getName());
        
        // 3. 生成运单号
        String trackingNumber = logisticsSystem.generateTrackingNumber(shipment.getShipmentId());
        System.out.println("生成运单号: " + trackingNumber);
        
        // 4. 更新发货状态
        logisticsSystem.updateShipmentStatus(shipment.getShipmentId(), Shipment.Status.IN_TRANSIT);
        
        // 5. 模拟送达
        logisticsSystem.deliverShipment(shipment.getShipmentId());
        
        // 查询最终物流信息
        Shipment finalShipment = logisticsSystem.getShipment(shipment.getShipmentId());
        System.out.println("\n最终物流信息:");
        System.out.println("发货单号: " + finalShipment.getShipmentId());
        System.out.println("运单号: " + finalShipment.getTrackingNumber());
        System.out.println("承运商: " + finalShipment.getCarrier().getName());
        System.out.println("状态: " + finalShipment.getStatus());
        System.out.println("发货日期: " + finalShipment.getShipDate());
        System.out.println("送达日期: " + finalShipment.getDeliveryDate());
    }
    
    // 初始化常用承运商
    private void initializeCarriers() {
        carriers.put("SF", new Carrier("SF", "顺丰速运", "95338"));
        carriers.put("STO", new Carrier("STO", "申通快递", "95543"));
        carriers.put("YT", new Carrier("YT", "圆通速递", "95554"));
        carriers.put("ZTO", new Carrier("ZTO", "中通快递", "95311"));
    }
    
    // 创建发货单
    public Shipment createShipment(Order order) {
        String shipmentId = "SH" + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
        Shipment shipment = new Shipment(
            shipmentId,
            order.getOrderId(),
            order.getShippingAddress(),
            order.getItems()
        );
        shipments.put(shipmentId, shipment);
        return shipment;
    }
    
    // 分配承运商
    public Carrier assignCarrier(String shipmentId) {
        Shipment shipment = shipments.get(shipmentId);
        if (shipment == null) {
            throw new IllegalArgumentException("无效的发货单ID");
        }
        
        // 简单逻辑：根据订单重量选择承运商
        double totalWeight = calculateTotalWeight(shipment.getItems());
        Carrier carrier;
        
        if (totalWeight > 5.0) { // 重货选择顺丰
            carrier = carriers.get("SF");
        } else { // 普通货物选择中通
            carrier = carriers.get("ZTO");
        }
        
        shipment.setCarrier(carrier);
        return carrier;
    }
    
    // 生成运单号
    public String generateTrackingNumber(String shipmentId) {
        Shipment shipment = shipments.get(shipmentId);
        if (shipment == null || shipment.getCarrier() == null) {
            throw new IllegalStateException("发货单未分配承运商");
        }
        
        String trackingNumber = shipment.getCarrier().getCode() + 
                              LocalDate.now().getYear() + 
                              UUID.randomUUID().toString().substring(0, 10).toUpperCase();
        shipment.setTrackingNumber(trackingNumber);
        return trackingNumber;
    }
    
    // 更新发货状态
    public void updateShipmentStatus(String shipmentId, Shipment.Status status) {
        Shipment shipment = shipments.get(shipmentId);
        if (shipment == null) {
            throw new IllegalArgumentException("无效的发货单ID");
        }
        shipment.setStatus(status);
        
        if (status == Shipment.Status.SHIPPED) {
            shipment.setShipDate(LocalDate.now());
        }
    }
    
    // 标记为已送达
    public void deliverShipment(String shipmentId) {
        Shipment shipment = shipments.get(shipmentId);
        if (shipment == null) {
            throw new IllegalArgumentException("无效的发货单ID");
        }
        shipment.setStatus(Shipment.Status.DELIVERED);
        shipment.setDeliveryDate(LocalDate.now());
    }
    
    // 获取发货单信息
    public Shipment getShipment(String shipmentId) {
        return shipments.get(shipmentId);
    }
    
    // 计算订单总重量（简化版）
    private double calculateTotalWeight(List<OrderItem> items) {
        // 实际项目中应从产品数据库获取重量信息
        // 这里使用简化逻辑：笔记本电脑5kg，其他物品0.5kg每个
        return items.stream()
            .mapToDouble(item -> item.getProductId().equals("P1001") ? 5.0 : 0.5 * item.getQuantity())
            .sum();
    }
    
    // 承运商类
    public static class Carrier {
        private String code;
        private String name;
        private String contact;
        
        public Carrier(String code, String name, String contact) {
            this.code = code;
            this.name = name;
            this.contact = contact;
        }
        
        public String getCode() { return code; }
        public String getName() { return name; }
        public String getContact() { return contact; }
    }
    
    // 发货单类
    public static class Shipment {
        private String shipmentId;
        private String orderId;
        private String trackingNumber;
        private Carrier carrier;
        private String shippingAddress;
        private List<OrderItem> items;
        private Status status;
        private LocalDate shipDate;
        private LocalDate deliveryDate;
        
        public Shipment(String shipmentId, String orderId, String shippingAddress, List<OrderItem> items) {
            this.shipmentId = shipmentId;
            this.orderId = orderId;
            this.shippingAddress = shippingAddress;
            this.items = items;
            this.status = Status.PREPARING;
        }
        
        public enum Status {
            PREPARING,    // 准备中
            PICKED_UP,   // 已取件
            IN_TRANSIT,   // 运输中
            DELIVERED,    // 已送达
            RETURNED     // 已退回
        }
        
        // Getter和Setter方法
        public String getShipmentId() { return shipmentId; }
        public String getOrderId() { return orderId; }
        public String getTrackingNumber() { return trackingNumber; }
        public void setTrackingNumber(String trackingNumber) { this.trackingNumber = trackingNumber; }
        public Carrier getCarrier() { return carrier; }
        public void setCarrier(Carrier carrier) { this.carrier = carrier; }
        public String getShippingAddress() { return shippingAddress; }
        public List<OrderItem> getItems() { return items; }
        public Status getStatus() { return status; }
        public void setStatus(Status status) { this.status = status; }
        public LocalDate getShipDate() { return shipDate; }
        public void setShipDate(LocalDate shipDate) { this.shipDate = shipDate; }
        public LocalDate getDeliveryDate() { return deliveryDate; }
        public void setDeliveryDate(LocalDate deliveryDate) { this.deliveryDate = deliveryDate; }
    }
}